﻿Imports SdlDotNet.Graphics
Imports SdlDotNet.Graphics.Sprites
Imports SdlDotNet.Input
Imports SdlDotNet.Audio
Imports System.Drawing

Public Class Gameplay
    Implements IScreen

    Private Players(4) As Player
    Private CurrentPlayer As Player

    Private Background As Sprite
    Private PlayerTurnMessage As TextSprite
    Private NormalFont As SdlDotNet.Graphics.Font = FontFactory.Plain16pt
    Private SmallBoldFont As SdlDotNet.Graphics.Font = FontFactory.BoldSmall

    Private AvatarPositions(5) As Point
    Private CurrentPlayerAvatarPosition As New Point(11, 486)

    Private InformationMessages As MultilineMessageBox
    Private InventoryDisplay As New InventoryDisplayPanel()
    Private WithEvents Menu As GameplayMenuContainer

    Private _selectingTarget As TargetSelectionType = TargetSelectionType.None
    Private SelectedWarhead As MissileAndWarheadTypes = MissileAndWarheadTypes.None

    Private TemporaryDrawableEntities As New List(Of ITemporaryDrawableEntity)

    Public Event Build(ByRef player As Player)
    Public Event Propaganda(ByRef player As Player, ByRef targetCity As City, ByRef targetPlayer As Player)
    Public Event DeployMissile(ByRef player As Player, ByVal type As MissileAndWarheadTypes)
    Public Event DeployBomber(ByRef player As Player)
    Public Event DeployAntiAircraft(ByRef player As Player)
    Public Event DeployAntiMissile(ByRef player As Player)
    Public Event LaunchMissile(ByRef player As Player, ByVal warheadType As MissileAndWarheadTypes, ByRef targetCIty As City, ByRef targetPlayer As Player)
    Public Event Bomb(ByRef player As Player, ByVal warheadType As MissileAndWarheadTypes, ByRef targetCity As City, ByRef targetPlayer As Player)
    Public Event MissileDestroyedByAntiMissile(ByRef defendingPlayer As Player)

    Private Property SelectingTarget() As TargetSelectionType
        Get
            Return _selectingTarget
        End Get
        Set(ByVal value As TargetSelectionType)
            If (value = TargetSelectionType.None) Then
                Cursor.Instance().Status = Cursor.PointerType.Standard
            Else
                Cursor.Instance().Status = Cursor.PointerType.Target
            End If

            _selectingTarget = value
        End Set
    End Property

    Public Sub New(ByRef players() As Player, ByRef currentPlayer As Player)
        Me.Players = players
        Me.CurrentPlayer = currentPlayer
        InitializeAvatarPositions()
        InitializeUserInterface()
        InitializeSprites()
        SetPlayerTurn(currentPlayer)
    End Sub

    Public Sub Draw(ByRef display As Surface) Implements IScreen.Draw
        Try
            display.Blit(Background)

            InformationMessages.Draw(display)

            CurrentPlayer.Avatar.DrawMedium(display, CurrentPlayerAvatarPosition)
            display.Blit(PlayerTurnMessage)

            If (CurrentPlayer.HumanControlled) Then
                InventoryDisplay.Draw(display)
                Menu.Draw(display)
            End If

            For i As Integer = 0 To Players.Length - 1
                Players(i).Avatar.DrawSmall(display, AvatarPositions(i))
            Next

            For Each player As Player In Players
                player.Cities.Draw(display)
                player.CommandCenter.Draw(display)
            Next

            For Each player As Player In Players
                If (player.DeployedBomber IsNot Nothing) Then
                    player.DeployedBomber.Draw(display)
                End If
            Next

            For i As Integer = 0 To TemporaryDrawableEntities.Count - 1
                If (TemporaryDrawableEntities(i) IsNot Nothing) Then
                    TemporaryDrawableEntities(i).Draw(display)
                End If
            Next
        Catch ex As Exception
            'this is stupid and shouldn't be here. problem with some indexes and things changing while the drawing is going on
        End Try
    End Sub

    Public Sub SetPlayerTurn(ByRef currentPlayer As Player)
        SelectingTarget = TargetSelectionType.None
        Me.CurrentPlayer = currentPlayer
        PlayerTurnMessage.Text = "Player " & currentPlayer.PlayerNumber
        InventoryDisplay.ShowInventory(currentPlayer.Inventory)
        Menu.ShowMenuForPlayer(currentPlayer)
    End Sub

    Public Sub AddTextToInformationWindow(ByVal text As String)
        InformationMessages.AddTextToBuffer(text)
    End Sub

    Public Sub AddCurrentPlayerMessageToInformation(ByVal text As String)
        InformationMessages.AddTextToBuffer("Player " & CurrentPlayer.PlayerNumber & " " & text)
    End Sub

    Private Sub InitializeSprites()
        Background = New Sprite(New Surface("Resources\images\game\GameBackground.jpg"), New Point(0, 0))
        PlayerTurnMessage = New TextSprite("", SmallBoldFont, Color.Gray, True, New Point(13, 570))
    End Sub

    Public Sub InitializeUserInterface()
        Menu = New GameplayMenuContainer(New Point(131, 480), CurrentPlayer)
        InformationMessages = New MultilineMessageBox(New Point(507, 492))
        InventoryDisplay.ShowInventory(CurrentPlayer.Inventory)
    End Sub

    Public Sub InitializeAvatarPositions()
        AvatarPositions(0) = New Point(366, 243)
        AvatarPositions(1) = New Point(65, 56)
        AvatarPositions(2) = New Point(645, 78)
        AvatarPositions(3) = New Point(657, 378)
        AvatarPositions(4) = New Point(22, 416)
    End Sub

    Public Sub CreateMissile(ByVal startPosition As Point, ByVal targetCity As City, ByRef targetPlayer As Player, ByVal amountOfDamageToDo As Integer)
        Dim missile As New Missile(startPosition, targetPlayer, targetCity, amountOfDamageToDo)
        AddHandler missile.NoLongerInUse, AddressOf RemoveTemporaryEntity
        AddHandler missile.Explosion, AddressOf CreateNuclearExplosion
        AddHandler missile.MissileWasADud, AddressOf MissileWasADud
        AddHandler missile.MissileDestroyedByAntiMissile, AddressOf MissileDestroyedByAntiMissileDefense

        TemporaryDrawableEntities.Add(missile)
    End Sub

    Public Sub CreatePlayerMigration(ByRef startCity As City, ByVal destinationCity As City, ByVal numberOfPeople As Integer)
        Dim migration As New PopulationMigration(startCity, destinationCity, numberOfPeople)
        AddHandler migration.NoLongerInUse, AddressOf RemoveTemporaryEntity
        TemporaryDrawableEntities.Add(migration)
    End Sub

    Public Sub CreateNuclearExplosion(ByVal position As Point)
        Dim NuclearExplosion As New NuclearExplosion(position)
        AddHandler NuclearExplosion.NoLongerInUse, AddressOf RemoveTemporaryEntity
        TemporaryDrawableEntities.Add(NuclearExplosion)
    End Sub

    Public Sub CreateExplosion(ByVal position As Point)
        Dim Explosion As New Explosion(position)
        AddHandler Explosion.NoLongerInUse, AddressOf RemoveTemporaryEntity
        TemporaryDrawableEntities.Add(Explosion)
    End Sub

    Private Sub TargetSelected(ByRef targetPlayer As Player, ByRef targetCity As City)
        If (SelectingTarget = TargetSelectionType.LaunchingMissile) Then
            RaiseEvent LaunchMissile(CurrentPlayer, SelectedWarhead, targetCity, targetPlayer)
        ElseIf (SelectingTarget = TargetSelectionType.LaunchingBomber) Then
            RaiseEvent Bomb(CurrentPlayer, SelectedWarhead, targetCity, targetPlayer)
        ElseIf (SelectingTarget = TargetSelectionType.Propaganda) Then
            RaiseEvent Propaganda(CurrentPlayer, targetCity, targetPlayer)
        End If
    End Sub

    Private Sub MissileWasADud(ByRef sender As Missile)
        InformationMessages.AddTextToBuffer("Missile was a dud!")
    End Sub

    Private Sub MissileDestroyedByAntiMissileDefense(ByRef defendingPlayer As Player)
        RaiseEvent MissileDestroyedByAntiMissile(defendingPlayer)
    End Sub

    Private Sub RemoveTemporaryEntity(ByRef entity As ITemporaryDrawableEntity)
        TemporaryDrawableEntities.Remove(entity)
        entity.Dispose()
    End Sub

    Public Sub Dispose() Implements IScreen.Dispose
        NormalFont.Dispose()
        SmallBoldFont.Dispose()
        PlayerTurnMessage.Dispose()
        Background.Dispose()
    End Sub

    Public Sub HandleKeyboardUp(ByVal sender As Object, ByVal e As SdlDotNet.Input.KeyboardEventArgs) Implements IScreen.HandleKeyboardUp
        ' do nothing
    End Sub

    Public Sub HandleMouseButtonUp(ByVal sender As Object, ByVal e As SdlDotNet.Input.MouseButtonEventArgs) Implements IScreen.HandleMouseButtonUp
        If (CurrentPlayer.HumanControlled <> False) Then
            If (SelectingTarget <> TargetSelectionType.None) Then
                For Each player As Player In Players
                    For Each city As City In player.Cities.cities
                        If (city.IntersectsWithPoint(e.Position)) Then
                            TargetSelected(player, city)
                            Exit Sub
                        End If
                    Next
                Next
            End If
            Menu.HandleMouseButtonUp(sender, e)
        End If
    End Sub

    Public Sub HandleMouseMotion(ByVal sender As Object, ByVal e As SdlDotNet.Input.MouseMotionEventArgs) Implements IScreen.HandleMouseMotion
        Menu.HandleMouseMotion(sender, e)
    End Sub

    Private Sub Menu_ClickedBombButton(ByVal warheadType As MissileAndWarheadTypes) Handles Menu.ClickedBombButton
        SelectedWarhead = warheadType
        SelectingTarget = TargetSelectionType.LaunchingBomber
    End Sub

    Private Sub Menu_ClickedBuildButton() Handles Menu.ClickedBuildButton
        RaiseEvent Build(CurrentPlayer)
    End Sub

    Private Sub Menu_ClickedDeployAntiAircraft() Handles Menu.ClickedDeployAntiAircraft
        RaiseEvent DeployAntiAircraft(CurrentPlayer)
    End Sub

    Private Sub Menu_ClickedDeployAntiMissile() Handles Menu.ClickedDeployAntiMissile
        RaiseEvent DeployAntiMissile(CurrentPlayer)
    End Sub

    Private Sub Menu_ClickedDeployBomber() Handles Menu.ClickedDeployBomber
        RaiseEvent DeployBomber(CurrentPlayer)
    End Sub

    Private Sub Menu_ClickedDeployMissile(ByVal missileType As MissileAndWarheadTypes) Handles Menu.ClickedDeployMissile
        RaiseEvent DeployMissile(CurrentPlayer, missileType)
    End Sub

    Private Sub Menu_ClickedLaunchMissile(ByVal warheadType As MissileAndWarheadTypes) Handles Menu.ClickedLaunchMissile
        SelectedWarhead = warheadType
        SelectingTarget = TargetSelectionType.LaunchingMissile
    End Sub

    Private Sub Menu_ClickedPropagandaButton() Handles Menu.ClickedPropagandaButton
        SelectingTarget = TargetSelectionType.Propaganda
    End Sub
End Class
